Lombok 常用方法
参考资料 Java中优雅的使用Lombok
什么是 Lombok
Lombok 是一种 Java实用工具,可用来帮助开发人员消除 Java 的冗长的代码,尤其是对于简单的 Java 对象(POJO), 它通过注释实现这一目的。一个标准的 Java bean 一般具有若干属性,每个属性具有 getter()
和 setter()
方法,Lombok 中也用到了注解,它在编译源代码期间自动帮我们生成这些方法,并没有如反射那样降低程序的性能。所以 JVM 实际运行的代码,和我们手动编写的包含了各种工具方法的类相同。
配置环境
安装插件等下次用到再补充
添加 Maven 依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.18</version>
<scope>provided</scope>
</dependency>
注解方法一览
val: final 像动态语言一样,声明一个 final 的变量。
var: 同JDK10,就是类型推断
@Data:注解在类上,将类提供的所有属性都添加get、set方法,并添加、equals、canEquals、hashCode、toString方法
@Setter:注解在类上,为所有属性添加set方法、注解在属性上为该属性提供set方法
@Getter:注解在类上,为所有的属性添加get方法、注解在属性上为该属性提供get方法
@NotNull:在参数中使用时,如果调用时传了null值,就会抛出空指针异常
@Synchronized 用于方法,可以锁定指定的对象,如果不指定,则默认创建一个对象锁定
@Log 作用于类,创建一个log属性
@Builder:使用builder模式创建对象
@NoArgsConstructor:创建一个无参构造函数
@AllArgsConstructor:创建一个全参构造函数
@ToString:创建一个toString方法
@Accessors(chain = true)使用链式设置属性,set方法返回的是this对象。
@RequiredArgsConstructor:创建对象, 例: 在class上添加@RequiredArgsConstructor(staticName = "of")会创建生成一个静态方法
@UtilityClass:工具类
@ExtensionMethod:设置父类
@FieldDefaults:设置属性的使用范围,如private、public等,也可以设置属性是否被final修饰。
@Cleanup: 关闭流、连接点。
@EqualsAndHashCode:重写equals和hashcode方法。
@toString:创建toString方法。
@Cleanup: 用于流等可以不需要关闭使用流对象.
申明是 final 类型
public static void main(String[] args) {
val setVar = new HashSet<String>();
val listsVar = new ArrayList<String>();
val mapVar = new HashMap<String, String>();
//=>上面代码相当于如下:
final Set<String> setVar2 = new HashSet<>();
final List<String> listsVar2 = new ArrayList<>();
final Map<String, String> maps2 = new HashMap<>();
}
非空检查
@NonNull
注解能够为方法或构造函数的参数提供非空检查。
public void notNullExample(@NonNull String string) {
//方法内的代码
}
//=>上面代码相当于如下:
public void notNullExample(String string) {
if (string != null) {
//方法内的代码相当于如下:
} else {
throw new NullPointerException("null");
}
}
自动释放资源
@Cleanup
注解能够自动释放资源。
public void jedisExample(String[] args) {
try {
@Cleanup Jedis jedis = redisService.getJedis();
} catch (Exception ex) {
logger.error(“Jedis异常:”,ex)
}
//=>上面代码相当于如下:
Jedis jedis= null;
try {
jedis = redisService.getJedis();
} catch (Exception e) {
logger.error(“Jedis异常:”,ex)
} finally {
if (jedis != null) {
try {
jedis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
自动生成 Getter、Setter
@Getter/@Setter
注解可以针对类的属性字段自动生成 Get/Set 方法。
public class OrderCreateDemoReq{
@Getter
@Setter
private String customerId;
@Setter
@Getter
private String poolId;
//其他代码……
}
//上面请求Req类的代码相当于如下:
public class OrderCreateDemoReq{
private String customerId;
private String poolId;
public String getCustomerId(){
return customerId;
}
public String getPoolId(){
return poolId;
}
public void setCustomerId(String customerId){
this.customerId = customerId;
}
public void setPoolId(String poolId){
this.pool = pool;
}
}
生成 ToString
@ToString
注解,为使用该注解的类生成一个 toString 方法,默认的 toString 格式为:
ClassName(fieldName=fieldValue ,fieldName1=fieldValue)
@ToString(callSuper=true,exclude="someExcludedField")
public class Demo extends Bar {
private boolean someBoolean = true;
private String someStringField;
private float someExcludedField;
}
//上面代码相当于如下:
public class Demo extends Bar {
private boolean someBoolean = true;
private String someStringField;
private float someExcludedField;
@Override
public String toString() {
return "Foo(super=" + super.toString() +
", someBoolean=" + someBoolean +
", someStringField=" + someStringField + ")";
}
}
自动生成 equals 和 hashCode 方法
@EqualsAndHashCode(exclude = {"id"}, callSuper =true)
public class LombokDemo extends Demo{
private int id;
private String name;
private String gender;
}
//上面代码相当于如下:
public class LombokDemo extends Demo{
private int id;
private String name;
private String gender;
@Override
public boolean equals(final Object o) {
if (o == this) return true;
if (o == null) return false;
if (o.getClass() != this.getClass()) return false;
if (!super.equals(o)) return false;
final LombokDemo other = (LombokDemo)o;
if (this.name == null ? other.name != null : !this.name.equals(other.name)) return false;
if (this.gender == null ? other.gender != null : !this.gender.equals(other.gender)) return false;
return true;
}
@Override
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = result * PRIME + super.hashCode();
result = result * PRIME + (this.name == null ? 0 : this.name.hashCode());
result = result * PRIME + (this.gender == null ? 0 : this.gender.hashCode());
return result;
}
}
生成几种构造方法
@NoArgsConstructor
, @RequiredArgsConstructor
, @AllArgsConstructor
,这几个注解分别为类自动生成了无参构造器、指定参数的构造器和包含所有参数的构造器。
@RequiredArgsConstructor(staticName = "of")
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class ConstructorExample<T> {
private int x, y;
@NonNull private T description;
@NoArgsConstructor
public static class NoArgsExample {
@NonNull private String field;
}
}
//上面代码相当于如下:
@RequiredArgsConstructor(staticName = "of")
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class ConstructorExample<T> {
private int x, y;
@NonNull private T description;
@NoArgsConstructor
public static class NoArgsExample {
@NonNull private String field;
}
}
public class ConstructorExample<T> {
private int x, y;
@NonNull private T description;
private ConstructorExample(T description) {
if (description == null) throw new NullPointerException("description");
this.description = description;
}
public static <T> ConstructorExample<T> of(T description) {
return new ConstructorExample<T>(description);
}
@java.beans.ConstructorProperties({"x", "y", "description"})
protected ConstructorExample(int x, int y, T description) {
if (description == null) throw new NullPointerException("description");
this.x = x;
this.y = y;
this.description = description;
}
public static class NoArgsExample {
@NonNull private String field;
public NoArgsExample() {
}
}
}
Data 注解全部生成
@Data
注解作用比较全,其包含注解的集合 @ToString
,@EqualsAndHashCode
,所有字段的 @Getter
和所有非 final 字段的 @Setter
, @RequiredArgsConstructor
。其示例代码可以参考上面几个注解的组合。
建造者模式和单例
@Builder
注解提供了一种比较推崇的构建值对象的方式。
@Singular
用于创建单例
@Builder
public class BuilderExample {
private String name;
private int age;
@Singular private Set<String> occupations;
}
//上面代码相当于如下:
public class BuilderExample {
private String name;
private int age;
private Set<String> occupations;
BuilderExample(String name, int age, Set<String> occupations) {
this.name = name;
this.age = age;
this.occupations = occupations;
}
public static BuilderExampleBuilder builder() {
return new BuilderExampleBuilder();
}
public static class BuilderExampleBuilder {
private String name;
private int age;
private java.util.ArrayList<String> occupations;
BuilderExampleBuilder() {
}
public BuilderExampleBuilder name(String name) {
this.name = name;
return this;
}
public BuilderExampleBuilder age(int age) {
this.age = age;
return this;
}
public BuilderExampleBuilder occupation(String occupation) {
if (this.occupations == null) {
this.occupations = new java.util.ArrayList<String>();
}
this.occupations.add(occupation);
return this;
}
public BuilderExampleBuilder occupations(Collection<? extends String> occupations) {
if (this.occupations == null) {
this.occupations = new java.util.ArrayList<String>();
}
this.occupations.addAll(occupations);
return this;
}
public BuilderExampleBuilder clearOccupations() {
if (this.occupations != null) {
this.occupations.clear();
}
return this;
}
public BuilderExample build() {
Set<String> occupations = new HashSet<>();
return new BuilderExample(name, age, occupations);
}
@Override
public String toString() {
return "BuilderExample.BuilderExampleBuilder(name = " + this.name + ", age = " + this.age + ", occupations = " + this.occupations + ")";
}
}
}
@Synchronized 注解
@Synchronized
注解类似 Java 中的 Synchronized 关键字,但是可以隐藏同步锁。
public class SynchronizedExample {
private final Object readLock = new Object();
@Synchronized
public static void hello() {
System.out.println("world");
}
@Synchronized("readLock")
public void foo() {
System.out.println("bar");
}
//上面代码相当于如下:
public class SynchronizedExample {
private static final Object $LOCK = new Object[0];
private final Object readLock = new Object();
public static void hello() {
synchronized($LOCK) {
System.out.println("world");
}
}
public void foo() {
synchronized(readLock) {
System.out.println("bar");
}
}
}